home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
PROGRAMM
/
ASSEMBLE
/
0938.ZIP
/
KEGELUNX.ARC
/
MV.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-06-02
|
6KB
|
268 lines
page 66,132
;---- mv.com ------------------------------------------------
; Usage: mv from to
; or: mv file {file {file...}} directory
; Moves files; cannot move across file systems.
; Useful for moving files to different directory.
; Not really very robust; doesn't like drive specs; not too smart.
; Sept 5 Dank: Fixed case mv \fred\*.* . bug by adding dirbuf2
; 6/2/86 DRK: added better error message for filetype!=directory if >2 args
;---------------------------------------------------------------
extrn _args:near,_shift:near,argc:word,argv:word
extrn ffirst:near,fnext:near,fnam:byte,finder:word
basefn equ 30 ; offset from finder of base filename
stderr equ 2
code segment public 'CODE'
assume cs:code,ds:code,es:code
f_attrib equ 21 ; offset from DTA of file attrib
org 100h ; this is a .com program, unfortunately
main proc near
jmp mv
main endp
db 27
db '[2J', 13, 10
db 'mv, 1984 & 1986 by DRK.', 13, 10
db 'How long did it take you to try typing me?', 13, 10
umsg: db 'usage: mv file newfilename', 13, 10
db ' or: mv file {file {file ...}} newdirectory', 13, 10
db " Don't use drive letters.", 13, 10
ulen = $ - offset umsg
db 26
movmsg: db '?mv: error moving files', 13, 10
movlen = $ - offset movmsg
drmsg: db '?mv: last arg is not a directory', 13, 10
drlen = $ - offset drmsg
lastarg dw ? ; pointer to last argument
lastargisdir db ? ; true if last argument is a directory
renaming db ? ; boolean- true if just rename
newfname dw ? ; pointer to new filename
dirbuf db 64 dup (?) ; holds current directory
dirbuf2 db 64 dup (?) ; holds destination sometimes
mv proc near
; Get arguments.
call _args
; Check # of arguments- must be > 1
cmp argc,1
ja usageok
jmp usage
usageok:
; Get last argument; it's referred to often.
mov si, argc
add si, si
mov si, argv[si]
mov lastarg, si
mov lastargisdir, 0
mov dx, si
mov ax, 4300h
int 21h ; Get file mode bits; err if no file.
jc lastnotdir
test cx, 10h ; true if directory
jz lastnotdir
mov lastargisdir, 1 ; must be 0 or 1
lastnotdir:
;------------- Check lastarg for special cases ------------
; \, /
mov si, lastarg
cld
lodsb
cmp al, '/'
jz dest_maybe_root
cmp al, '\'
jnz dest_not_root
dest_maybe_root:
lodsb
cmp al, 0
jnz dest_not_root
dest_root:
inc lastarg ; make it point to null
jmp not_renaming
dest_not_root:
;----- . and .. ---------------------------
; First, just in case, get the current directory.
lea si, dirbuf
mov byte ptr [si], '\'
inc si
mov dl, 0
mov ah, 47h
INT 21h
; Now check the destination of the move.
mov si, lastarg
lodsb
cmp al, '.'
jnz no_special_case
lodsb
cmp al, 0
jnz parent
; moving to current directory. Use dirbuf as destination.
mov si, offset dirbuf
mov lastarg, si
jmp not_renaming
parent:
cmp al, '.'
jnz no_special_case
lodsb
cmp al, 0
jnz no_special_case
; Moving to parent directory.
; We must find the next-to-last \ and turn it into a null
; in order to make the name of our parent directory.
; But first, verify that we're not the top level.
lea si, dirbuf
cmp byte ptr [si][1], 0
jz no_parent
mov di, 0
parlp: lodsb
cmp al, '\'
jz par_slash
cmp al, '/'
jnz par_nslash
par_slash: mov di, si
dec di
par_nslash:
cmp al, 0
jnz parlp
cmp di, offset dirbuf
jnz got_parent
; If parent is top level, need to turn char After
; slash to a null.
inc di
got_parent:
mov al, 0
stosb
jmp not_renaming
no_parent:
jmp move_error
no_special_case:
;-------------------------------------------------
; renaming = !lastargisdir;
; if (argc > 2 && renaming) error("What you tryin t'pull?");
mov al, lastargisdir
xor al, 1
mov renaming, al
cmp argc, 2
jz wants_rename
or al, al
jz not_renaming
lea dx, drmsg
mov cx, drlen
jmp err
wants_rename:
not_renaming:
;----- Main Loop -------
; do {
; find_first_matching(argv[2]);
; repeat
; build_dest_filename;
; move;
; until renaming or (not find_next);
; shift;
; } while (argc != 1) and not renaming;
while_loop:
mov dx, argv[2]
mov cx, 0
call ffirst
jc while_done
rept_loop:
; Make the destination filename.
; if (renaming) then
; newfname := lastarg
; else
; newfname := lastarg + '\' + basefilename;
test renaming, -1
jz mn_not_ren
push lastarg
pop newfname
jmp short mn_done
mn_not_ren:
cld ; setup for string move
mov di, offset dirbuf2
mov newfname, di
mov si, lastarg
mn_cl: lodsb
cmp al, 0
jz mn_addslash
stosb
jmp mn_cl
mn_addslash: mov al, '\'
stosb
mov si, finder
add si, basefn;
mn_cl2: lodsb
stosb
cmp al, 0
jnz mn_cl2
mn_done:
;------------------------------------
; Move.
mov dx, offset fnam
mov di, newfname
mov ah, 56h
int 21h
jc move_error
; until renaming or (not find_next);
test renaming, -1
jnz while_done
call fnext
jnc rept_loop
; shift;
call _shift
dec argc
cmp argc, 1
jz while_done
jmp while_loop
while_done:
mov al, 0 ; no error
exit:
mov ah, 4ch
int 21h ; terminate process, return status in AL.
;------------------------------------------------------------
usage:
mov dx, offset umsg
mov cx, ulen
jmp short err
move_error:
mov dx, offset movmsg
mov cx, movlen
err: mov ah, 40h
mov bx, stderr
int 21h
mov al, 1
jmp exit
mv endp
code ends
end main